/* COPYRIGHT_CHUNFENG */
#ifndef CF_FDEVENT_H
#define CF_FDEVENT_H

#include <sys/select.h>
#include "cf_list.h"
typedef struct cf_fdevent CFFdevent;
typedef struct cf_fdevents CFFdevents;
struct cf_fdevent{
	int fd;
	int(*read_action)(CFFdevents* events, CFFdevent* event, int fd, void* read_parameter);
	int(*write_action)(CFFdevents* events, CFFdevent* event, int fd, void* write_parameter);
	void *read_parameter;
	void *write_parameter;
    CFListHead list;
};

struct cf_fdevents{
	CFFdevent event_head;
	fd_set read_fdset;
	fd_set write_fdset;
	int read_max_fd;
	int write_max_fd;
};

typedef int(*read_action_fun)(CFFdevents* events, CFFdevent* event, int fd, void* data);
typedef int(*write_action_fun)(CFFdevents* events, CFFdevent* event, int fd, void* data);


CFFdevent* cf_fdevent_new(int fd, 
					read_action_fun read_action, void* read_parameter,
					write_action_fun write_action, void* write_parameter);
#define CFFdeventNew    cf_fdevent_new
int cf_fdevent_init(CFFdevent* self, int fd, 
					read_action_fun read_action,   /* NULL means no monitor on read ability */
					void* read_parameter,
					write_action_fun write_action,  /* NULL means no monitor on write ability */
					void* write_parameter);
#define CFFdeventInit   cf_fdevent_init
int cf_fdevent_free(CFFdevent* self);
#define CFFdeventFree   cf_fdevent_free
int cf_fdevent_append(CFFdevent* self, CFFdevent* new_event);
#define CFFdeventAppend cf_fdevent_append
int cf_fdevent_exit(CFFdevent* this);
#define CFFdeventExit   cf_fdevent_exit

int cf_fdevents_init(CFFdevents* this);
#define CFFdeventsInit  cf_fdevents_init
int cf_fdevents_exit(CFFdevents* this);
#define CFFdeventsExit  cf_fdevents_exit
CFFdevents* cf_fdevents_new();
#define CFFdeventsNew   cf_fdevents_new
int cf_fdevents_free(CFFdevents* self);
#define CFFdeventsFree  cf_fdevents_free
int cf_fdevents_add(CFFdevents* self, CFFdevent* new_event);
#define CFFdeventsAdd   cf_fdevents_add
int cf_fdevents_del(CFFdevents* self, CFFdevent* event_to_del);
#define CFFdeventsDel   cf_fdevents_del
int cf_fdevents_del_all(CFFdevents* this);
#define CFFdeventsDelAll    cf_fdevents_del_all
int cf_fdevents_del_free(CFFdevents* self, CFFdevent* event_to_del);
#define CFFdeventsDelFree   cf_fdevents_del_free
int cf_fdevents_del_close(CFFdevents* this, CFFdevent* event);
#define CFFdeventsDelClose  cf_fdevents_del_close
int cf_fdevents_del_close_free(CFFdevents* this, CFFdevent* event);
#define CFFdeventsDelCloseFree  cf_fdevents_del_close_free
int cf_fdevents_trigger(CFFdevents* self);
#define CFFdeventsLoop  cf_fdevents_trigger


typedef struct cf_event_action{
    CFFdevents* events;
    CFFdevent* event;
    int(*action)(CFFdevents* events, CFFdevent* event, int fd, void* context);
    int fd;
    void* context;
    CFListHead list;
}CFEventAction;

int cf_event_action_init(CFEventAction* new_action, int(*action)(CFFdevents* events, CFFdevent* event, int fd, void* context), CFFdevents* events, CFFdevent* event, int fd, void* context);
CFEventAction* cf_event_action_new(int(*action)(CFFdevents* events, CFFdevent* event, int fd, void* context), CFFdevents* events, CFFdevent* event, int fd, void* context);
int cf_event_action_free(CFEventAction* action);
int cf_event_actions_add(CFEventAction* head, CFEventAction* to_add);
CFEventAction* cf_event_actions_safe_add(CFEventAction* head, CFEventAction* to_add);
int cf_event_actions_del(CFEventAction* head, CFEventAction* to_del);
CFEventAction* cf_event_action_get_next(CFEventAction* action);
int cf_event_actions_go(CFEventAction* head);
int cf_event_actions_free(CFEventAction* head);

#endif
